/**
 * 
 */
package handwritten.gesture;

import gui.JFEditorWindows;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.xml.bind.annotation.XmlType;

import utility.math.Transformation;
import utility.math.Vector2D;

/**
 * @author tioz
 *
 */




@XmlType (
	    name = "##default", 
	    propOrder = {""}, 
	    namespace = "##default" 
	    //factoryClass = DEFAULT.class, 
	    //factoryMethod = ""
	)
public class MultiGesture implements Serializable,Cloneable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -961625466873068944L;
	
	ArrayList<Gesture> collection;	
	
	/**
	 * 
	 */
	public MultiGesture() {
		collection= new ArrayList<Gesture>();
	}
	
	public MultiGesture(ArrayList<Gesture> col) {
		collection= col;
	}

	
	

	public ArrayList<Gesture> getGesture() {
		return collection;
	}

	public void add(Gesture gest)
	{
		collection.add(gest);
	}
	
	public void add(ArrayList<Vector2D> path)
	{
		collection.add(new Gesture(path));
	}
		
	
	public void  fillPath(int[][] cell){
		for(int i= 0;i < collection.size();i++ )
		{
			collection.get(i).fillPath(cell);
		}
	}
	
	public void fillPath(int[][] cell,Vector2D offset){
		for(int i= 0;i < collection.size();i++ )
		{
			collection.get(i).fillPath(cell,offset);
		}
	}
	
	public Vector2D startOfLetter(){
		if(collection.size() !=0)
			return collection.get(0).startOfPath();
		else
			return null;
	}
	
	
	public void paint(Graphics2D g2d ){
		for(Gesture g:collection){
			g.paint(g2d);
		}
	}

	/*
	 * temporary, for test purpose 
	 */
	public void paintInNewFrame(String name)
	{
		class Charpane extends JPanel{
		
		private static final long serialVersionUID = -6103363210406492922L;
		MultiGesture toshow;
		
		public Charpane(MultiGesture ge){
					toshow = (MultiGesture)ge.clone();		
		}
		
		public void paint(Graphics g){
			super.paintComponent(g); 
			Graphics2D g2 = (Graphics2D)g;
			//Line2D.Float line2 = new Line2D.Float(5,5,20,20);
			//g2.draw(line2);
			
			toshow.paint(g2);
		 }

		};
			JFrame frame = new JFrame(name);
			Charpane pane = new Charpane(this);
			
			
			frame.setSize(500,500);
			pane.setSize(500,500);
			pane.setBackground(new Color(0,255,255));
			pane.setVisible(true);
			
			
			frame.getContentPane().setLayout(new BorderLayout());
			frame.getContentPane().add(pane, BorderLayout.CENTER);
			//frame.getContentPane().add(new JButton("pouette"),BorderLayout.SOUTH);
			
			frame.setVisible(true);
			pane.repaint();

	}
	
	/**
	 * @return the max y coordinate
	 */
	public Vector2D  top(){
		//FIXME not realy clean but allow range based loop
		Vector2D top = this.startOfLetter();
		Vector2D t;
		for(Gesture g : collection)
		{
			t = g.top();
			if(top.getY()< t.getY());
			top= t;
		}
		return top;
	}
	
	
		/**
		 * @return return the min y corrdinate
		 */
		public Vector2D bottom(){
			Vector2D bottom = this.startOfLetter();
			Vector2D b;
			for(Gesture c : collection)
			{
				b= c.bottom();
				if(bottom.getY()> b.getY());
					bottom= b;
			}
			return bottom;
		}
		
		/**
		 * @return the max y coordinate
		 */
		public Vector2D  right(){
			Vector2D right = this.startOfLetter();
			Vector2D r;
			for(Gesture g : collection)
			{
				r=g.right();
				if(right.getX()< r.getX());
				right= r;
			}
			return right;
		}
		
		
		/**
		 * @return return the min x coordinate
		 */
		public Vector2D left(){
			Vector2D left = this.startOfLetter();
			Vector2D l;
			for(Gesture g : collection)
			{
				l = g.left();
				if(left.getX()> l.getX());
					left= l;
			}
			return  left;
		}
		
		
		/**
		 * @return the height of the gesture
		 */
		public double height(){
			return (top().minus(bottom())).getY();
		}
		
		/**
		 * @return the width of the gesture
		 */
		public double width(){
			return right().minus(left()).getX();
		}
	
		public ArrayList<Vector2D> intersectionBetweenGesture(){
			
			ArrayList<Vector2D> intersection = new ArrayList<Vector2D>();
			
			for(int i=0; i< collection.size();i++)
			{
				for(int j=i+1; j< collection.size();j++)
				{
						intersection.addAll(collection.get(i).intersection(collection.get(j)));				
				}
			}
			return intersection;
		}
		
		//!!! this function do a deep copie. not really java standard !!!
		/*
		 * (non-Javadoc)
		 * @see java.lang.Object#clone()
		 */
		public Object clone() {
			MultiGesture gest= null;
			try
			{
				gest = (MultiGesture) super.clone();
				
			}
			catch(CloneNotSupportedException e)
			{
				e.printStackTrace(System.err);
			}	
			
			ArrayList<Gesture> deepClone = new ArrayList<Gesture>();
			for(Gesture g: collection)
			{
				deepClone.add((Gesture)g.clone());
			}
			gest.collection = deepClone;		
			
			return gest;
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result
					+ ((collection == null) ? 0 : collection.hashCode());
			return result;
		}

		/* (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			MultiGesture other = (MultiGesture) obj;
			if (collection == null) {
				if (other.collection != null)
					return false;
			} else if (!collection.equals(other.collection))
				return false;
			return true;
		}

		/**
		 * @return the collection
		 */
		public ArrayList<Gesture> getCollection() {
			return collection;
		}

		/**
		 * @param collection the collection to set
		 */
		public void setCollection(ArrayList<Gesture> collection) {
			this.collection = collection;
		}
		
		public Vector2D centerOfMass(){
			
			Vector2D center = new Vector2D(0,0);
			double weight=0;
			double tmp=0;
			
			for(Gesture g: collection)
			{
				tmp=g.nPoint();
				weight+=tmp;
				center.thisPlus(g.centerOfMass().time(tmp));		
			}
			center.thisTime(1/weight);
			
			return center;
		}
		
		/**
		 * @param translate all the coordinate of the gesture
		 */
		public void translate(Vector2D v)
		{
			for(Gesture g: collection)
			{
				g.translate(v);
			}
		}
		public void transform(Transformation t)
		{
			for(Gesture g: collection)
			{
				g.transform(t);
			}
		}
		
		
		public double pathLength(){
			double length=0;			
			for(Gesture g: collection)
			{
				length+= g.pathLength();
			}
			return length;
		}
		
		public int numberOfGesture(){
			return collection.size();
		}
		
		public Gesture get(int i){
			return collection.get(i);
		}
		
}
